﻿// Nail framework
//
// Copyright © Frank Nagl, 2009-2012
// admin@franknagl.de
// www.franknagl.de
//
// Some source code snippets from 
// http://dotnet-snippets.de/dns/erkennen-ob-eine-exe-oder-dll-als-64bit-kompiliert-wurde-SID1181.aspx
//
//
namespace Nail
{
    using System;
    using System.IO;
    using System.Windows.Forms;

    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length == 1)
            {
                FileStream fs = new FileStream(args[0], FileMode.Open);
                CheckIsFile64Bit(fs);
                fs.Close();
            }
            else
            {
                MessageBox.Show("You need ONE file as argument.");
            }
        }    


// ReSharper disable UnusedMethodReturnValue.Local
        private static bool CheckIsFile64Bit(FileStream filestream)
// ReSharper restore UnusedMethodReturnValue.Local
        {
            bool ret = false;
            string msg = "";

            Byte[] data = new Byte[4];
            filestream.Seek(0x3c, SeekOrigin.Begin);
            filestream.Read(data, 0, 4);
            int offset = BitConverter.ToInt32(data, 0);

            if (offset > 0x3c)
            {
                data = new Byte[4];
                filestream.Seek(offset, SeekOrigin.Begin);
                filestream.Read(data, 0, 4);

                if ((data[0] == 0x50)
                    && (data[1] == 0x45)
                    && (data[2] == 0x00)
                    && (data[3] == 0x00))
                {

                    // Read COFF File Header
                    data = new Byte[20];
                    filestream.Read(data, 0, 20);
                    //int _machine = BitConverter.ToInt16(data, 0);
                    //msg += string.Format("Machine: 0x{0}" + System.Environment.NewLine, _machine.ToString("X4"));
                    //int _numberOfSections = BitConverter.ToInt16(_data, 2);
                    //msg += string.Format("NumberOfSections: 0x{0}" + System.Environment.NewLine, _numberOfSections.ToString("X4"));
                    //int _timeDateStamp = BitConverter.ToInt32(_data, 4);
                    //double _secs = Convert.ToDouble(_timeDateStamp);
                    //DateTime _dt = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(_secs);
                    //DateTime _tds = System.TimeZone.CurrentTimeZone.ToLocalTime(_dt);
                    //msg += string.Format("TimeDateStamp: {0} (0x{1})" + System.Environment.NewLine, _tds.ToString(), _timeDateStamp.ToString("X8"));
                    //int _pointerToSymbolTable = BitConverter.ToInt32(_data, 8);
                    //msg += string.Format("PointerToSymbolTable: 0x{0}" + System.Environment.NewLine, _pointerToSymbolTable.ToString("X8"));
                    //int _numberOfSymbols = BitConverter.ToInt32(_data, 12);
                    //msg += string.Format("NumberOfSymbols: 0x{0}" + System.Environment.NewLine, _numberOfSymbols.ToString("X4"));
                    //int _sizeOfOptionalHeader = BitConverter.ToInt16(_data, 16);
                    //msg += string.Format("SizeOfOptionalHeader: 0x{0}" + System.Environment.NewLine, _sizeOfOptionalHeader.ToString("X4"));
                    //int _characteristics = BitConverter.ToInt16(_data, 18);
                    //msg += string.Format("Characteristics: 0x{0}" + System.Environment.NewLine, _characteristics.ToString("X4"));

                    // Read Optional Header
                    data = new Byte[2];
                    filestream.Read(data, 0, 2);
                    int magicNumber = BitConverter.ToInt16(data, 0);
                    //msg += string.Format("Magic Number: 0x{0}" + System.Environment.NewLine, _magicNumber.ToString("X4"));
                    if (magicNumber == 0x010b)
                        msg += String.Format("File {0} is 32bit!" + System.Environment.NewLine, filestream.Name);
                    else if (magicNumber == 0x020b)
                    {
                        msg += String.Format("File {0} is 64bit!" + System.Environment.NewLine, filestream.Name);
                        ret = true;
                    }

                    MessageBox.Show(msg);
                }
                else
                    MessageBox.Show("No PE File!");
            }
            else
                MessageBox.Show("Wrong Offset or no PE File!");

            return ret;
        }
}
}